home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / util / cli / MakePath.lha / MakePath / src / MakePath.c < prev    next >
C/C++ Source or Header  |  1997-09-27  |  6KB  |  291 lines

  1. /********************************************************************
  2. *
  3. *          File: MakePath.c
  4. *   Description: Main code module for MakePath
  5. *        Author: Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
  6. *       Version: 1.1a
  7. *        Status: Public domain
  8. *  Last changed: 27 Sep 1997
  9. *
  10. ********************************************************************/
  11.  
  12. #define __USE_SYSBASE
  13.  
  14. #include <proto/dos.h>
  15. #include <proto/exec.h>
  16. #include <exec/memory.h>
  17.  
  18. #include <string.h>
  19.  
  20. /* Uncomment the next line to activate debugging */
  21. //#define DEBUG 1
  22. #include "debug.h"
  23.  
  24. UBYTE fver[] = "$VER: MakePath 1.1a " __AMIGADATE__ " Ole Martin Bjørndalen";
  25.  
  26. /****** CliTools/MakePath *******************************************
  27. *
  28. *    NAME
  29. *        MakePath -- Creates or completes path.
  30. *
  31. *    TEMPLATE
  32. *        PATH/M/A
  33. *
  34. *    FUNCTION
  35. *        MakePath attempts to create or complete the path you
  36. *        specify. Directories that do not exist will be created.
  37. *        If MakePath returns without errors, the full path is
  38. *        guaranteed to be there.
  39. *
  40. *        MakePath does not create icons for the new drawers.
  41. *
  42. *    ARGUMENTS
  43. *        PATH - One or more paths to create
  44. *
  45. *    RESULT
  46. *        Returns FAIL if something went wrong, else OK.
  47. *
  48. *    EXAMPLES
  49. *        MakePath a/short/path
  50. *        MakePath a/path another/path
  51. *        MakePath this//is//perfectly//legal
  52. *
  53. *    NOTES
  54. *        Unlike MakeDir, MakePath will not fail if a directory
  55. *        already exists. You may want to know this when writing
  56. *        scripts.
  57. *
  58. *    BUGS
  59. *        None known
  60. *
  61. *    AUTHOR
  62. *        Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
  63. *
  64. *    SEE ALSO
  65. *        C:MakeDir
  66. *
  67. *****************************************************************************
  68. *
  69. */
  70.  
  71. BOOL MakePath(struct ExecBase *SysBase,
  72.                 struct DosLibrary *DOSBase,
  73.                 STRPTR path);
  74.  
  75. /*
  76.     Define an argument structure for ReadArgs().
  77.     If find this is more readable than using a
  78.     LONG array, even for one argument
  79. */
  80. struct Arguments {
  81.     STRPTR *path;
  82. };
  83.  
  84. #define TEMPLATE "PATH/M/A"
  85.  
  86. /*
  87.     There is no startup code, so we'll have to do
  88.     all the setup ourselves. Most of the work is done
  89.     by dos.library,    though.
  90. */
  91. int startup(void)
  92. {
  93.     LONG result = RETURN_OK;
  94.     struct ExecBase *SysBase;
  95.     struct Process *proc;
  96.  
  97.     SysBase = (*((struct ExecBase **) 4));
  98.     proc = (struct Process *)FindTask(NULL);
  99.  
  100.     /*
  101.         Make sure we don't crash if started from WB
  102.     */
  103.     if(proc->pr_CLI)
  104.     {
  105.         struct DosLibrary *DOSBase;
  106.  
  107.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36L))
  108.         {
  109.             struct RDArgs *rdargs;
  110.             struct Arguments args = { NULL };    
  111.  
  112.             if(rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL))
  113.             {
  114.                 int i;
  115.  
  116.                 for(i = 0; args.path[i]; i++)
  117.                 {
  118.                     if(!MakePath(SysBase, DOSBase, args.path[i]))
  119.                     {
  120.                         /* Failed! Let's get outta here! */
  121.                         result = RETURN_FAIL;
  122.                         break;
  123.                     }
  124.                 }
  125.             }
  126.             else
  127.             {
  128.                 PrintFault(IoErr(), NULL);
  129.                 result = RETURN_FAIL;
  130.             }
  131.  
  132.             CloseLibrary((struct Library *)DOSBase);
  133.         }
  134.         else
  135.         {
  136.             proc->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;            
  137.         }
  138.     }
  139.     else
  140.     {
  141.         /*
  142.             Started from WB. Reply startup
  143.             message and exit gracefully
  144.         */
  145.         struct Message *msg;
  146.         
  147.         WaitPort(&proc->pr_MsgPort);
  148.         
  149.         if(msg = GetMsg(&proc->pr_MsgPort))
  150.         {
  151.             Forbid();
  152.             ReplyMsg(msg);
  153.         }
  154.     }
  155.  
  156.     return result;
  157. }
  158.  
  159. /*
  160.     Create the actual path. If this fails, an
  161.     error code is printed and FALSE is returned.
  162.     
  163.     I use SetIoErr() because it allows me to
  164.     use PrintFault() for my own error conditions.
  165.     Thus, MakePath is fully localized.
  166. */
  167. BOOL MakePath(struct ExecBase *SysBase,
  168.                 struct DosLibrary *DOSBase,
  169.                 STRPTR path)
  170. {
  171.     BOOL success = FALSE;
  172.     UBYTE *buffer;
  173.     
  174.     D(bug("MakePath(%s)\n", path));
  175.     
  176.     /* Allocate a temporary buffer to hold the path */
  177.     if(buffer = AllocVec(strlen(path) + 1, MEMF_ANY))
  178.     {
  179.         LONG p;
  180.  
  181. //        D(bug("Buffer allocated\n"));
  182.  
  183.         /*
  184.             Iterate through the buffer and stop
  185.             between path components
  186.         */
  187.         for(p = 0; ;p++)
  188.         {
  189.             if(path[p] == '/' || path[p] == '\0')
  190.             {
  191.                 BPTR lock;
  192.                 
  193.                 /*
  194.                     Temporary NULL termination
  195.                 */
  196.                 buffer[p] = '\0';
  197.  
  198.                 D(bug("Lock(%s)\n", buffer));
  199.                 
  200.                 /*
  201.                     Expect the worst. This will be
  202.                     set back to TRUE if all went well
  203.                 */
  204.                 success = FALSE;
  205.             
  206.                 /* Does the directory exist? */
  207.                 if(lock = Lock(buffer, ACCESS_READ))
  208.                 {
  209.                     __aligned struct FileInfoBlock fib;
  210.                 
  211.                     D(bug("Examine(%s)\n", buffer));
  212.                 
  213.                     /* Yes, but is it really a directory? */
  214.                     if(Examine(lock, &fib))
  215.                     {
  216.                         if(fib.fib_DirEntryType > 0)
  217.                         {
  218.                             success = TRUE;
  219.                         }
  220.                         else
  221.                         {
  222.                             /* fail */
  223.                             SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  224.                         }
  225.                     }
  226.                     /* else fail */
  227.                 }
  228.                 else
  229.                 {
  230.                     /*
  231.                         If I didn't test this, the
  232.                         "please insert volume X"
  233.                         requester would open twice.
  234.                         Also, if a serious error has
  235.                         occured, calling CreateDir()
  236.                         is rather pointless.
  237.                     */
  238.                     if(IoErr() == ERROR_OBJECT_NOT_FOUND)
  239.                     {
  240.                         D(bug("CreateDir(%s)\n", buffer));
  241.                                                 
  242.                         if(lock = CreateDir(buffer))
  243.                         {
  244.                             success = TRUE;
  245.                         }
  246.                         else
  247.                         {
  248.                             /* fail */
  249.                             D(bug("CreateDir() failed!\n"));
  250.                         }
  251.                     }
  252.                     /* else fail */
  253.                     
  254.                 } /* Lock() */
  255.                 
  256.                 if(lock)
  257.                     UnLock(lock);
  258.                     
  259.                 if(!success)
  260.                 {
  261.                     /*
  262.                         An error occured.
  263.                         Inform user and bail out
  264.                     */
  265.                     PrintFault(IoErr(), buffer);
  266.                     break;
  267.                 }
  268.                 
  269.                 if(path[p] == '\0')
  270.                 {
  271.                     /* Reached the end of the string */
  272.                     break;
  273.                 }
  274.  
  275.             } /* if('/' || '\0') */
  276.             
  277.             /* Copy character to work buffer */
  278.             buffer[p] = path[p];
  279.  
  280.         } /* for() */
  281.     }
  282.     else
  283.     {
  284.         PrintFault(ERROR_NO_FREE_STORE, NULL);
  285.     }
  286.  
  287.     D(bug("%s\n", success ? "SUCCESS" : "FAILURE"));
  288.  
  289.     return success;
  290. }
  291.